<?php

namespace App\Http\Controllers\Client;

use App\Http\Requests\Client\Login\LoginUpload;
use App\Models\Bills;
use App\Models\Service;
use App\Models\StationBills;
use App\Models\UserAuthentication;
use App\Repositories\UserLogRepository;
use Auth;
use Faker\Provider\DateTime;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use JWTAuth;
use Exception;
use App\Models\Courier;
use App\Http\Controllers\Controller;
use App\Http\Requests\Client\Login\LoginRequest;
use App\Http\Requests\Client\Login\AuthenticationCreate;
use App\Repositories\CourierRepository;
use Tymon\JWTAuth\Exceptions\JWTException;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redis;

/**
 * 处理用户登录逻辑控制器
 *
 * Date: 2018/04/26
 * @author Tenny
 * @package App\Http\Controllers\Auth
 */
class LoginController extends Controller
{
    use AuthenticatesUsers;

    const COURIER_TYPE = 2;
    const AUTHENTICATION_IS_ACCESS = 1;
    const AUTHENTICATION_ORDER_ID = 0;
    const REDIS_EXPIRES_FOR_DAY = 86400;

    /**
     * 处理用户登录逻辑
     *
     * Date: 2018/05/24
     * @author Tenny
     * @param LoginRequest $request
     * @return array
     * @throws
     */
    public function login(LoginRequest $request)
    {

        // 验证用户输入凭证
        $this->validate($request, [
            'phone' => ['required', 'regex:/^(1[3456789])\d{9}$/'],
            'password' => 'required|string|min:6|max:18',
        ], [
            'phone.required' => '请输入手机号',
            'phone.regex' => '请输入正确的手机号',
            'password.required' => '请输入密码',
            'password.string' => '请输入正确格式的密码',
            'password.min' => '密码不得少于:min个字符',
            'password.max' => '密码不得少于:max个字符',
        ]);

        // 获取凭证
        $credentials = [
            $this->username() => $request->get('phone'),
            'password' => $request->get('password')
        ];

        $courier = Courier::query()
            ->where('phone', $request->get('phone'))
            ->withTrashed()
            ->first();
        if (!$courier || optional($courier)->status === null || optional($courier)->service_id === null) {
            return failed('您尚不是共派派送员！您可以联系附近站点，成为共派派送员', 404);
        } else if ($courier->status != 1 || $courier->service_id == 0 || ($courier instanceof Courier && $courier->trashed())) {
            return failed('您暂无绑定站点', 404);
        }
        try {
            if (!$token = $this->guard('courier')->attempt($credentials)) {
                return failed('认证失败，用户名或密码不正确', 401);
            }
        } catch (JWTException $exception) {
            return internalError();
        }
        $service = Service::query()->where('id', '=', $courier->service_id)->first();
        if (!$service || optional($service)->status === null || $service->status == 2) {
            return failed('您所在的站点已停业', 403);
        }
        $user = Auth::guard('courier')->user();
        $courierRepository = new CourierRepository;
        $res = $courierRepository->CourierInfo($user->id);
        unset($user);
        return success([
            'id' => $res->id,
            'name' => $res->name,
            'phone' => $res->phone,
            'service_name' => $res->service_name,
            'is_authentication' => $res->is_authentication,
            'jurisdiction' => $res->jurisdiction,
            'avatar' => $res->avatar,
            'token_type' => 'Bearer',
            'access_token' => $token,
            'expires_in' => config('jwt.ttl') * 60
        ]);
    }

    /**
     * 处理用户注销逻辑
     *
     * Date: 2018/05/24
     * @author Tenny
     * @return \Illuminate\Http\JsonResponse
     */
    public function logout()
    {
        try {
            $this->guard()->logout();
        } catch (Exception $exception) {
            return internalError();
        }
        return respond([], '注销成功');
    }

    /**
     * 处理用户认证逻辑
     *
     * Date: 2018/05/24
     * @author Tenny
     * @param AuthenticationCreate $request
     * @return \Illuminate\Http\JsonResponse
     * throws  \Illuminate\Database\QueryException
     * throws  \App\Exceptions\GeneralException
     * @throws Exception
     */
    public function authentication(AuthenticationCreate $request)
    {
        $user = Auth::user();
        $uid = $user->id;
        $service_id = $user->service_id;
        $name = $user->name;
        $ip = $request->getClientIp();
        $attributes = $this->extractInputFromRules($request, $request->rules());
        $attributes['uid'] = $uid;
        $attributes['type'] = self::COURIER_TYPE;//类型为快递员
        $attributes['status'] = self::AUTHENTICATION_IS_ACCESS;//状态为默认认证通过
        \DB::beginTransaction();
        try {
            $id_card = UserAuthentication::query()
                ->where('uid', '=', $uid)
                ->where('type', '=', self::COURIER_TYPE)
                ->orderBy('created_at', 'desc')
                ->first();
            if ($id_card) {
                $id_card->heads_path = $attributes['heads_path'];
                $id_card->tails_path = $attributes['tails_path'];
                $id_card->type = $attributes['type'];
                $id_card->status = $attributes['status'];
                $id_card->save();
            } else {
                UserAuthentication::create($attributes);
            }
            //修改Courier的认证状态
            \DB::table('courier')
                ->where('id', $uid)
                ->update(['is_authentication' => 1]);
            \DB::commit();
        } catch (\Illuminate\Database\QueryException $ex) {
            \DB::rollback();
            return failed('未知错误', 500);
        }
        //删除快递员缓存
        $redis_key = sprintf('COURIER_INFO_V1_%d', $uid);
        Redis::del($redis_key);
        //记录日志
        $operation = '进行了身份证认证';
        $history = $actuality = null;
        $type = 0;//快递员
        $userLogRepository = new UserLogRepository();
        $userLogRepository->myLog($uid, $service_id, $name, $operation, $history, $actuality, self::AUTHENTICATION_ORDER_ID, $ip, $type);
        return respond([], '认证成功');
    }

    /**
     * 定义用于验证的用户的字段
     *
     * Date: 2018/04/26
     * @author Tenny
     * @return string
     */
    public function username()
    {
        return 'phone';
    }

    /**
     * 定义默认的Guard
     *
     * Date: 2018/04/26
     * @author Tenny
     * @param $guard
     * @return \Illuminate\Contracts\Auth\Guard|\Illuminate\Contracts\Auth\StatefulGuard
     */
    public function guard($guard = 'courier')
    {
        return Auth::guard($guard);
    }

    /**
     * 上传图片
     *
     * Date: 2018/5/27
     * @author Tenny
     * @param LoginUpload $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function upload(LoginUpload $request)
    {
        $file = $request->file('cover');
        if ($file->isValid()) {
            $path = $file->store('identification', 'public');
            return success(['path' => Storage::url($path)]);
        }
        return failed('文件上传失败');
    }

    /**
     * 共派条款
     *
     * Date: 2018/06/05
     * @author Tenny
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function agreement(Request $request)
    {
        $redis_key = sprintf('GP_AGREEMENT_V1');
        if (!Redis::exists($redis_key)) {
            $agreement = \DB::table('agreement')
                ->select(['*'])
                ->first();
            Redis::setex($redis_key, self::REDIS_EXPIRES_FOR_DAY, json_encode($agreement, true));
        } else {
            $res = Redis::get($redis_key);
            $agreement = json_decode($res, true);
        }
        return success($agreement);
    }
}
